package com.xm.queue.task2;

import com.xm.limiter.Limiter;
import com.xm.limiter.SlidingWindowLimiter02;

/**
 * 工具类
 */
public class TaskUtil {
    private static final int LIMIT = 100;// QPS
    private static final Limiter LIMITER_PUT = new SlidingWindowLimiter02(LIMIT, 1000, 100);// 限流存放任务，平均每10毫秒接收 1 个请求
    private static final Limiter LIMITER_Take = new SlidingWindowLimiter02(LIMIT * TaskExecutor.CORE_POOL_SIZE, 1000, 100);// 限流拉取任务，平均每10毫秒消费 CORE_POOL_SIZE 个请求
    private static final int WORKER_NUM = TaskExecutor.CPU_CORES / 2;

    private TaskUtil() {}

    private static volatile TaskManager taskManager;

    public static TaskManager getInstance() {
        if (taskManager == null) {
            synchronized (TaskUtil.class) {
                if (taskManager == null) {
//                    taskManager = new TaskManager(0, true, true);
                    taskManager = new TaskManager(1, true, null);
//                    taskManager = new TaskManager(2, false, null);
                    start(WORKER_NUM);
                }
            }
        }
        return taskManager;
    }

    /**
     * 启用工人
     * @param workerNum 工人数量
     */
    public static void start(int workerNum) {
        for (int i = 0; i < workerNum; i++) {
            TaskExecutor.submit(new TaskWorker(getInstance(), i));
        }
    }

    public static void addTask(ITask task) {
        try {
            getInstance().addTask(task);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public static int getQueueSize() {
        return getInstance().getQueueSize();
    }

    /**
     * 尝试获取 put 资格
     */
    public static boolean tryPutAcquire() {
        return LIMITER_PUT.tryAcquire();
    }

    /**
     * 尝试获取 poll 资格
     */
    public static boolean tryTakeAcquire() {
        return LIMITER_Take.tryAcquire();
    }
}
